class DateTime {
    constructor(date = new Date()) {
        if (date instanceof Date) {
            this._dateObj = date;
        } else {
            this._dateObj = new Date(date);
        }
    }
    static get(date = new Date()) {
        return new DateTime(date);
    }
    static add0(m) {
        return m < 10 ? '0' + m : m;
    }
    // 当前时间戳
    static now() {
        return ~~(Date.now() / 1000);
    }
    static nowMs() {
        return Date.now();
    }
    static format(date, format=null) {
        const y = date.getFullYear();
        const m = date.getMonth() + 1;
        const d = date.getDate();
        const h = date.getHours();
        const mm = date.getMinutes();
        const s = date.getSeconds();
        switch (format) {
            case 'date':
                return `${y}-${DateTime.add0(m)}-${DateTime.add0(d)}`;
            case 'time':
                return `${DateTime.add0(h)}:${DateTime.add0(mm)}:${DateTime.add0(s)}`;
            case 'datehour':
                return `${y}-${DateTime.add0(m)}-${DateTime.add0(d)}-${DateTime.add0(h)}`;
            default:
                return `${y}-${DateTime.add0(m)}-${DateTime.add0(d)} ${DateTime.add0(h)}:${DateTime.add0(mm)}:${DateTime.add0(s)}`;
        }
    }
    // 当前时间
    static nowDate() {
        return DateTime.format(new Date(), 'date');
    }
    static nowTime() {
        return DateTime.format(new Date(), 'time');
    }
    static nowDatetime() {
        return DateTime.format(new Date());
    }
    // 比较2个时间，1<2返回-1，1==2返回0，1>2返回1
    static compare(datetime1, datetime2) {
        const s1 = datetime1.timestampMs();
        const s2 = datetime2.timestampMs();
        if (s1<s2) {
            return -1;
        } else if (s1>s2) {
            return 1;
        } else {
            return 0;
        }
    }
    // DateTime对象
    dateObject() {
        return this._dateObj;
    }
    // 时间戳
    timestamp() {
        return ~~(this._dateObj.valueOf() / 1000);
    }
    timestampMs() {
        return this._dateObj.valueOf();
    }
    // 零点时间戳
    zeroPoint(timeZone = 8) {
        const tt = ~~(this._dateObj.valueOf() / 1000);
        return tt - tt % 86400 - timeZone * 3600;
    }
    // 得到标准时区的时间戳
    getUTCTimestamp(timeZone) {
        // 参数i为时区值数字，比如北京为东八区则输进8,纽约为西5区输入-5
        if (typeof timeZone !== 'number') return 0;
        const d = new Date();
        // 得到1970年一月一日到现在的秒数
        const len = d.getTime();
        // 本地时间与GMT时间的时间偏移差
        const offset = d.getTimezoneOffset() * 60000;
        // 得到现在的格林尼治时间
        const utcTime = len + offset;
        return utcTime + 3600000 * timeZone;
    }
    // 获取时间日期字符串
    datetime() {
        return DateTime.format(this._dateObj);
    }
    // 获取日期字符串
    date() {
        return DateTime.format(this._dateObj, 'date');
    }
    // 获取日期小时字符串
    dateHour() {
        return DateTime.format(this._dateObj, 'datehour');
    }
    // 获取时间字符串
    time() {
        return DateTime.format(this._dateObj, 'time');
    }
    // 获取年月日整数
    dateNumber() {
        const y = this._dateObj.getFullYear();
        const m = this._dateObj.getMonth() + 1;
        const d = this._dateObj.getDate();
        return y * 10000 + m * 100 + d;
    }
    // 获取年月日时分秒整数
    datetimeNumber() {
        const y = this._dateObj.getFullYear();
        const m = this._dateObj.getMonth() + 1;
        const d = this._dateObj.getDate();
        const h = this._dateObj.getHours();
        const mm = this._dateObj.getMinutes();
        const s = this._dateObj.getSeconds();
        return y*10000000000 + m*100000000 + d*1000000 + h*10000 + mm*100 + s;
    }
    // 获取UTC时间日期字符串
    datetimeUTC() {
        const y = this._dateObj.getUTCFullYear();
        const m = this._dateObj.getUTCMonth() + 1;
        const d = this._dateObj.getUTCDate();
        const h = this._dateObj.getUTCHours();
        const mm = this._dateObj.getUTCMinutes();
        const s = this._dateObj.getUTCSeconds();
        return `${y}-${DateTime.add0(m)}-${DateTime.add0(d)} ${DateTime.add0(h)}:${DateTime.add0(mm)}:${DateTime.add0(s)}`;
    }
    // 按秒计算
    addSecond(sec) {
        return new DateTime(this._dateObj.valueOf()+sec*1000);
    }
    // 按分钟计算
    addMinute(mt) {
        return new DateTime(this._dateObj.valueOf()+mt*60000);
    }
    // 按小时计算
    addHour(hour) {
        return new DateTime(this._dateObj.valueOf()+hour*3600000);
    }
    // 按天计算
    addDay(day) {
        return new DateTime(this._dateObj.valueOf()+day*86400000);
    }
    // 按周计算
    addWeek(week) {
        return new DateTime(this._dateObj.valueOf()+week*7*86400000);
    }
    // 按月计算
    addMonth(month) {
        const y = this._dateObj.getFullYear();
        const m = this._dateObj.getMonth();
        const d = this._dateObj.getDate();
        const h = this._dateObj.getHours();
        const mm = this._dateObj.getMinutes();
        const s = this._dateObj.getSeconds();
        return new DateTime(new Date(y+(m+month)/12, (m+month)%12, d, h, mm, s));
    }
    // 按年计算
    addYear(year) {
        const y = this._dateObj.getFullYear();
        const m = this._dateObj.getMonth();
        const d = this._dateObj.getDate();
        const h = this._dateObj.getHours();
        const mm = this._dateObj.getMinutes();
        const s = this._dateObj.getSeconds();
        return new DateTime(new Date(y+year, m, d, h, mm, s));
    }
    // 计算相差天数
    diffDays(date) {
        const s1 = this.timestamp();
        const s2 = date.timestamp();
        const diff = (s1-s2)/86400;
        return parseInt(diff);
    }
    // 计算相差小时数
    diffHours(date) {
        const s1 = this.timestamp();
        const s2 = date.timestamp();
        const diff = (s1-s2)/3600;
        return parseInt(diff);
    }
    // 获得本月第一天
    firstDayOfTheMonth() {
        const y = this._dateObj.getFullYear();
        const m = this._dateObj.getMonth();
        return new DateTime(new Date(y, m, 1));
    }
    // 获得本年第一天
    firstDayOfTheYear() {
        const y = this._dateObj.getFullYear();
        return new DateTime(y, 0, 1);
    }
    // 获得周的范围
    weekRange() {
        let d = this._dateObj.getDay();
        if (d==0) {
            d = 7;
        }
        let monday = this.addDay(1-d);
        let sunday = this.addDay(7-d);
        return[monday, sunday];
    }
    // 获得月的范围
    monthRange() {
        let first = this.firstDayOfTheMonth();
        let nextMonth = this.addMonth(1);
        let last = nextMonth.firstDayOfTheMonth();
        last = last.addDay(-1);
        return [first, last];
    }
    // 获得本年第几天
    getYearDays() {
        const y = this._dateObj.getFullYear();
        const m = this._dateObj.getMonth();
        const d = this._dateObj.getDate();

        let date1 = new Date(y, m, d),
            date2 = new Date(y, 0, 1);
        return Math.round((date1.valueOf() - date2.valueOf()) / 86400000);
    }
    // 获得本年第几周，默认周1是一周的第一天
    getYearWeeks(begin=1) {
        const y = this._dateObj.getFullYear();
        const m = this._dateObj.getMonth();
        const d = this._dateObj.getDate();
        /*
        begin：一周的第一天是周几
        date1：当前日期
        date2：当年第一天
        days：当前日期是今年第多少天
        用days+当前年的第一天的周差距的和在除以7就是本年第几周
        */
        let date1 = new Date(y, m, d),
            date2 = new Date(y, 0, 1),
            days = Math.round((date1.valueOf() - date2.valueOf()) / 86400000);
        return Math.ceil((days + ((date2.getDay() + 1) - begin)) / 7);
    }
}

module.exports = DateTime;

// let a = new DateTime();
// a = a.addMonth(8);
// console.log(a.datetime());